package com.morphiastic;

import java.util.HashMap;
import java.util.HashSet;
import java.util.Set;

import org.elasticsearch.common.transport.InetSocketTransportAddress;

import com.morphiastic.annotations.ElastiFieldBridge;



/**
 * Options for EStore initialization
 * 
 * 
 * @author Alex
 *
 */
public class ElasticStoreOptions {

	enum CONNECTION_MODE { NODE, TRANSPORT_CLIENT};
	
	private boolean forceIndexReCreation = false;
	
	private boolean asynchronousIndexation = false;
	private int workerThreads = 4;
	private Set<IndexationEventListener> indexationEventListeners = new HashSet<IndexationEventListener>();
	private Set<ElasticStoreLifecycleListener> elasticStoreLifeCycleListeners = new HashSet<ElasticStoreLifecycleListener>();
	
	
	
	//key = name, value = IndexedFieldBridge implementation instance
	private HashMap<String, IndexedFieldBridge> fieldBridges = new HashMap<String, IndexedFieldBridge>();
	
	
	private boolean clientOnly = true; //ES client only? defaults to true;
	
	private int numberOfShards = 1;
	private int numberOfReplicas = 0;
	
	private CONNECTION_MODE connectionMode = CONNECTION_MODE.NODE;
	
	InetSocketTransportAddress[] transportAddresses;
	String clusterName;
	
	
	
	/**
	 * @return the asynchronousIndexation
	 */
	public boolean isAsynchronousIndexation() {
		return asynchronousIndexation;
	}
	/**
	 * @param asynchronousIndexation the asynchronousIndexation to set
	 */
	public void setAsynchronousIndexation(boolean asynchronousIndexation) {
		this.asynchronousIndexation = asynchronousIndexation;
	}
	
	
	/**
	 * @return the workerThreads
	 */
	public int getWorkerThreads() {
		return workerThreads;
	}
	/**
	 * @param workerThreads the workerThreads to set
	 */
	public void setWorkerThreads(int workerThreads) {
		this.workerThreads = workerThreads;
	}
	

	/**
	 * @return the forceIndexReCreation
	 */
	public boolean isForceIndexReCreation() {
		return forceIndexReCreation;
	}
	/**
	 * @param forceIndexReCreation the foreIndexReCreation to set
	 */
	public void setForceIndexReCreation(boolean forceIndexReCreation) {
		this.forceIndexReCreation = forceIndexReCreation;
	}
	
	
	
	
	/**
	 * adds an indexation Event Listener to the list of listeners
	 * @param listener
	 */
	public void addIndexationEventListener(IndexationEventListener listener){
		indexationEventListeners.add(listener);
	}
	
	/**
	 * adds a lifecylce listener
	 * @param listener
	 */
	public void addElasticStoreLifeCycleListener(ElasticStoreLifecycleListener listener){
		elasticStoreLifeCycleListeners.add(listener);
	}
	/**
	 * @return the clientOnly
	 */
	public boolean isClientOnly() {
		return clientOnly;
	}
	/**
	 * @param clientOnly the clientOnly to set
	 */
	public void setClientOnly(boolean clientOnly) {
		this.clientOnly = clientOnly;
	}
	/**
	 * @return the numberOfShards
	 */
	public int getNumberOfShards() {
		return numberOfShards;
	}
	/**
	 * @param numberOfShards the numberOfShards to set
	 */
	public void setNumberOfShards(int numberOfShards) {
		this.numberOfShards = numberOfShards;
	}
	/**
	 * @return the numberOfReplicas
	 */
	public int getNumberOfReplicas() {
		return numberOfReplicas;
	}
	/**
	 * @param numberOfReplicas the numberOfReplicas to set
	 */
	public void setNumberOfReplicas(int numberOfReplicas) {
		this.numberOfReplicas = numberOfReplicas;
	}
	/**
	 * @return the connectionMode
	 */
	public CONNECTION_MODE getConnectionMode() {
		return connectionMode;
	}
	/**
	 * @param connectionMode the connectionMode to set
	 */
	public void setConnectionMode(CONNECTION_MODE connectionMode) {
		this.connectionMode = connectionMode;
	}
	/**
	 * @return the transportAddresses
	 */
	public InetSocketTransportAddress[] getTransportAddresses() {
		return transportAddresses;
	}
	/**
	 * @param transportAddresses the transportAddresses to set
	 */
	public void setTransportAddresses(
			InetSocketTransportAddress[] transportAddresses) {
		this.transportAddresses = transportAddresses;
	}
	/**
	 * @return the clusterName
	 */
	public String getClusterName() {
		return clusterName;
	}
	/**
	 * @param clusterName the clusterName to set
	 */
	public void setClusterName(String clusterName) {
		this.clusterName = clusterName;
	}
	/**
	 * @return the indexationEventListeners
	 */
	public Set<IndexationEventListener> getIndexationEventListeners() {
		return indexationEventListeners;
	}
	/**
	 * @return the elasticStoreLifeCycleListeners
	 */
	public Set<ElasticStoreLifecycleListener> getElasticStoreLifeCycleListeners() {
		return elasticStoreLifeCycleListeners;
	}
	
	/**
	 * Allows the user to add pre instatiated fieldBridges that the ElasticStore should be aware of 
	 * 
	 * Very useful if the fieldBridge does not have a no-argument constructor that cannot be instantiated automagically
	 * 
	 * 
     * if multiple instances of a same IndexedFieldBridge implementation are needed, the should be differentiated using different names
	 * 
	 * 
	 * //OLD DOC NOT VALID ANYMORE
	 * The first argument is an ElastiFieldBridgeAnnotation necessary to differentiate fieldBridges internally 
	 * and should be created by manually instantiating a new ElastiFieldBridge(){ <annotation params here> } 
	 * 
	 * if multiple instances of a same IndexedFieldBridge implementation are needed, the ElastiFieldBridge annotation should be used to 
	 * differentiate them for example by using a different name() parameter
	 * 
	 * @param fieldBridge
	 */
	public void addFieldBridge(String name, IndexedFieldBridge fieldBridge){
		fieldBridges.put(name,fieldBridge);
	}
	/**
	 * @return the fieldBridges
	 */
	public HashMap<String, IndexedFieldBridge> getFieldBridges() {
		return fieldBridges;
	}
	
	
}
